<?php

namespace common\services\myhtsq;

use common\entities\myhtsq\ContractReceivableEntity;
use common\entities\myhtsq\ErpUserEntity;
use common\error\ErrorCode;
use common\error\ErrorInfo;
use common\models\myhtsq\ContractReceivableModel;
use common\repositories\myhtsq\ContractEmailContactsRepository;
use common\repositories\myhtsq\ContractManageRepository;
use common\repositories\myhtsq\ContractPayinfoRepository;
use common\repositories\myhtsq\ContractSuppliersPaymentRepository;
use common\repositories\myhtsq\ErpUserRepository;
use common\services\BaseService;
use common\entities\ConfigEntity;
use common\models\myhtsq\InvoiceSummaryModel;
use common\repositories\myhtsq\ContractReceivableRepository;
use common\repositories\myhtsq\InvoiceRepository;
use common\repositories\myhtsq\InvoiceSummaryRepository;
use common\repositories\myhtsq\InvoiceReceivableRepository;
use common\repositories\myhtsq\InvoicePaymentRepository;
use common\services\common\EmailService;
use console\entities\ErpBusinessUnitEntity;
use Yii;
use yii\base\Exception;

/**
 * Description of ContractReceivable
 * 合同应收款管理服务
 * @author chenxc
 */
class ContractReceivableService extends BaseService
{

    public function __construct($config = array())
    {
        parent::__construct($config);
    }

    public function updateContractReceivable($receivable_id, $receivable_date, $payee_id)
    {
        $receivable_entity = ContractReceivableEntity::find()->where(['receivable_id' => $receivable_id])->one();
        if (isset($receivable_entity)) {
            if (!empty($receivable_date)) {
                $receivable_entity->receivable_date = $receivable_date;
            }
            if (!empty($payee_id)) {
                $receivable_entity->payee_id = $payee_id;
                $user_entity = ErpUserEntity::find()->where(['UserGUID' => $payee_id])->one();
                if (isset($user_entity)) {
                    $receivable_entity->department_id = $user_entity->DepartmentGUID;
                }
            }
            if (!empty($receivable_date) || !empty($payee_id)) {
                $receivable_entity->save();
            }
        }
    }

    /**
     * 根据合同ID获取对应的应收款项明细
     * @param string $contractId 合同id
     * @param boolean $withBadDebt 是否包含坏账
     * @return array
     */
    public function getReceivableInfoByContractId($contractId, $withBadDebt = true)
    {
        return ContractReceivableRepository::getReceivableInfoByContractId($contractId, $withBadDebt);
    }

    /**
     * 获取指定合同下的所有应收款金额
     * @param string $contractId 合同id
     * @return float
     */
    public function getReceivableTotalAmountByContractId($contractId)
    {
        return ContractReceivableRepository::getReceivableTotalAmountByContractId($contractId);
    }

    /**
     * 保存合同应收款项
     * @param $contractReceivableModel
     * @return boolean|string   失败|应收款项Guid
     */
//    public function saveContractReceivable($contractReceivableModel)
//    {
//        if ($contractReceivableModel->validate()) {
//            if (isset($contractReceivableModel->receivable_id) && !empty($contractReceivableModel->receivable_id)) {
//                //修改
//                $result = ContractReceivableRepository::updateContractReceivable($contractReceivableModel);
//            } else {
//                //新增
//                $result = ContractReceivableRepository::addContractReceivable($contractReceivableModel);
//            }
//
//            if (!$result) {
//                return self::setAndReturn(ContractReceivableRepository::getErrCode());
//            }
//
//            return $result;
//        } else {
//            return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_FORM_VERIFY_FAIL);
//        }
//    }

    /**
     * 保存合同应收款项
     * @param \common\models\myhtsq\ContractReceivableModel $contractReceivableModel
     * @param bool $isComeFromBusinessSystem 是否来自商机系统
     * @return boolean|string   失败|应收款项Guid
     */
    public function saveContractReceivable($contractReceivableModel, $isComeFromBusinessSystem = false)
    {
        if ($contractReceivableModel->validate()) {
            if ($isComeFromBusinessSystem === false) {
                // 开启事务
                $configDataBase = ConfigEntity::getDb();
                $trans = $configDataBase->beginTransaction();
                try {
                    if (isset($contractReceivableModel->receivable_id) && !empty($contractReceivableModel->receivable_id)) {
                        //修改
                        $resultUpdate = ContractReceivableRepository::updateContractReceivable($contractReceivableModel);
                        if ($resultUpdate === false) {
                            $trans->rollBack();
                            return self::setAndReturn(ContractReceivableRepository::getErrCode());
                        }
                    } else {
                        //新增
                        $resultAdd = ContractReceivableRepository::addContractReceivable($contractReceivableModel);
                        if ($resultAdd === false) {
                            $trans->rollBack();
                            return self::setAndReturn(ContractReceivableRepository::getErrCode());
                        }
                    }
                    //云客中成功更改了应收款时，需要向商机系统反馈
                    $resultSent = $this->sentReceivableDataToBusinessSystem($contractReceivableModel->contract_id);
                    if ($resultSent === false) {
                        $trans->rollBack();
                        return self::setAndReturn(__LINE__, '', '通知商机系统失败！');
                    }
                    $trans->commit();
                    return true;
                } catch (\Exception $e) {
                    $trans->rollBack();
                    return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_FORM_VERIFY_FAIL);
                }
            } else {
                //新增
                $result = ContractReceivableRepository::addContractReceivable($contractReceivableModel);
                return $result;
            }
        } else {
            return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_FORM_VERIFY_FAIL);
        }
    }

    /**
     * 变更应收款时，调用接口更新商机系统中的应收款
     * @param $contractId
     * @return bool
     * @throws \yii\base\InvalidConfigException
     */
    public function sentReceivableDataToBusinessSystem($contractId)
    {
        if ($contractId) {
            /** @var ErpUserRepository $erpUserRepository */
//            $erpUserRepository = \Yii::createObject(ErpUserRepository::className());
            try {
                $receivableData = $this->getReceivableInfoByContractId($contractId);
                $receivableDataToBusinessSystem = [];
                foreach ($receivableData as $receivable) {
                    //循环，组装商机系统需要的字段
                    $tmp = [];
                    $tmp['GatheringGUID'] = $receivable['receivable_id'];
                    $tmp['ContractGUID'] = $receivable['contract_id'];
                    $tmp['ReceiveAmount'] = $receivable['receivable_amount'];//应收款金额
                    $tmp['income_type'] = $receivable['revenue_type_name'];
                    $tmp['IncomeType'] = '云链';
                    $tmp['KxName'] = $receivable['receivable_item_name'];
                    $tmp['KxType'] = $receivable['money_category_item_name'];
                    $tmp['PayCondition'] = $receivable['payment_condition'];
                    $tmp['ReceiveDate'] = $receivable['receivable_date'];
                    $tmp['payee_id'] = $receivable['payee_id'];
                    $tmp['ParentGatheringGUID'] = '';
                    $tmp['CloudJointSales'] = '';
                    $tmp['remark'] = $receivable['remark'];
//                    $cloudJoinUser = $erpUserRepository->getUserById($receivable['unite_sales_id']);
//                    $tmp['CloudJointSalesName'] = $cloudJoinUser['UserName'];
                    $tmp['CloudJointSalesName'] = '';

                    if ($receivable['contract_property'] == null || $receivable['contract_property'] == '') {
                        $tmp['CloudSignType'] = '';
                    } elseif (intval($receivable['contract_property']) == 1) {
                        $tmp['CloudSignType'] = '续签';
                    } elseif (intval($receivable['contract_property']) == 0) {
                        $tmp['CloudSignType'] = '新签';
                    }

                    $receivableDataToBusinessSystem[] = $tmp;
                }

                $erpInterfaceService = \Yii::createObject(ErpInterfaceService::className());
                $updateBusinessSystemReceivableResult = $erpInterfaceService->updateBusinessSystemReceivable($receivableDataToBusinessSystem);
                return $updateBusinessSystemReceivableResult;
            } catch (\Exception $ex) {
                \Yii::error($ex->getMessage());
                throw $ex;
            }
        }
        return false;
    }

    /**
     * 删除应收款信息
     * @param string $receivableId 应收款ID
     * @return boolean true删除成功/false删除失败
     */
    public function deleteContractReceivable($receivableId)
    {
        $entity = ContractReceivableRepository::getContractReceivableById($receivableId);
        if (!isset($entity)) {
            return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_NOT_EXISTS);
        }

        // 开启事务
        $configDataBase = ConfigEntity::getDb();
        $trans = $configDataBase->beginTransaction();
        try {
            $affectedRowNum = $entity->delete();
            if ($affectedRowNum === false) {
                $trans->rollBack();
                return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_DELETE_FAIL);
            }

            //调用商机系统API，通知商机系统修改了应收款
            $sentResult = $this->sentReceivableDataToBusinessSystem($entity->contract_id);
            if ($sentResult === false) {
                $trans->rollBack();
                return self::setAndReturn(__LINE__, '', '通知商机系统失败!');
            }
            $trans->commit();
        } catch (\Exception $e) {
            $trans->rollBack();
            return self::setAndReturn(__LINE__, '', '通知商机系统失败:' . (string)$e);
        }


        return true;
    }

    /**
     * 保存合同应收款项拆分信息
     * @param $contractReceivableModel
     * @return boolean|string   失败|新拆分的应收款项Guid
     */
    public function splitContractReceivable($contractReceivableModel)
    {
        if ($contractReceivableModel->validate()) {
            $oldEntity = ContractReceivableRepository::getContractReceivableById($contractReceivableModel->old_receivable_id);
            if (!isset($oldEntity)) {
                return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_NOT_EXISTS);
            }

            if (floatval($oldEntity['billing_amount']) > 0 || floatval($oldEntity['received_amount']) > 0) {
                return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_HAS_FAPIAO_SPLIT_FORM_VERIFY_FAIL, '当前应收款已关联了发票，不允许拆分');
            }

            // 开启事务
            $configDataBase = ConfigEntity::getDb();
            $trans = $configDataBase->beginTransaction();

            try {
                //新增，记录父级的old_receivable_id
                $contractReceivableModel->old_receivable_id = $oldEntity->receivable_id;

                $resultNew = ContractReceivableRepository::addContractReceivable($contractReceivableModel);
                if ($resultNew === false) {
                    $trans->rollBack();
                    return self::setAndReturn(ContractReceivableRepository::getErrCode());
                }

                //把旧的记录内容也新增一条
                $contractReceivableModelOld = new ContractReceivableModel(['scenario' => 'splitontractreceivable']);
                $contractReceivableModelOld->receivable_amount = floatval($oldEntity->receivable_amount) - floatval($contractReceivableModel->receivable_amount);
                $contractReceivableModelOld->receivable_id = '';
                $contractReceivableModelOld->old_receivable_id = $contractReceivableModel->old_receivable_id;
                $contractReceivableModelOld->contract_id = $oldEntity->contract_id;
                $contractReceivableModelOld->receivable_item_id = $oldEntity->receivable_item_id;
                $contractReceivableModelOld->money_category_item_id = $oldEntity->money_category_item_id;
                $contractReceivableModelOld->revenue_type = $oldEntity->revenue_type;
                $contractReceivableModelOld->receivable_date = $oldEntity->receivable_date;
                $contractReceivableModelOld->payee_id = $oldEntity->payee_id;
                $contractReceivableModelOld->professional_line_id = $oldEntity->professional_line_id;
                $contractReceivableModelOld->payment_condition = $oldEntity->payment_condition;
                $contractReceivableModelOld->billing_amount = $oldEntity->billing_amount;
                $contractReceivableModelOld->received_amount = $oldEntity->received_amount;
                $contractReceivableModelOld->is_bad_debt = $oldEntity->is_bad_debt;
                $contractReceivableModelOld->is_operation = $oldEntity->is_operation;
                $contractReceivableModelOld->contract_property = $oldEntity->contract_property;
                $contractReceivableModelOld->remark = $contractReceivableModel->remark;
                $resultOld = ContractReceivableRepository::addContractReceivable($contractReceivableModelOld);
                if ($resultOld === false) {
                    $trans->rollBack();
                    return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_SPLIT_FAIL);
                }

                //删除旧的记录
                $resultDelete = $this->deleteContractReceivable($oldEntity->receivable_id);
                if ($resultDelete === false) {
                    $trans->rollBack();
                    return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_SPLIT_FAIL);
                }

                //调用商机系统API，通知商机系统修改了应收款
                $sentResult = $this->sentReceivableDataToBusinessSystem($oldEntity->contract_id);
                if ($sentResult === false) {
                    $trans->rollBack();
                    return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_SENT_BUSSENISS_FAIL, '通知商机系统失败!');
                }

                $trans->commit();

                return true;
            } catch (\Exception $e) {
                $trans->rollBack();
                return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_SPLIT_FORM_VERIFY_FAIL);
            }
        } else {
            return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_SPLIT_FORM_VERIFY_FAIL);
        }
    }

    /**
     * 保存合同应收款项责任人变更信息
     * @param $contractReceivableModel
     * @return boolean|string   失败|应收款项Guid
     */
    public function changeResponsiblePerson(ContractReceivableModel $contractReceivableModel)
    {
        if ($contractReceivableModel->validate()) {
            //修改
            // 开启事务
            $configDataBase = ConfigEntity::getDb();
            $trans = $configDataBase->beginTransaction();
            try {
                $result = ContractReceivableRepository::updateContractReceivable($contractReceivableModel);
                if ($result === false) {
                    $trans->rollBack();
                    return self::setAndReturn(ContractReceivableRepository::getErrCode());
                }

                $resultSent = $this->sentReceivableDataToBusinessSystem($contractReceivableModel->contract_id);
                if ($resultSent === false) {
                    $trans->rollBack();
                    return self::setAndReturn(__LINE__, '', '通知商机系统失败！');
                }

                $trans->commit();
                return $result;
            } catch (\Exception $e) {
                $trans->rollBack();
                return self::setAndReturn(__LINE__, '', '通知商机系统失败:' . (string)$e);
            }
        } else {
            return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_CHANGE_RECEIVABLE_DATE_FORM_VERIFY_FAIL);
        }
    }

    /**
     * 保存合同应收款项应收时间变更信息
     * @param $contractReceivableModel
     * @return boolean|string   失败|应收款项Guid
     */
    public function changeReceivableDate($contractReceivableModel)
    {
        if ($contractReceivableModel->validate()) {
            //修改
            $result = ContractReceivableRepository::updateContractReceivable($contractReceivableModel);
            if ($result === false) {
                return self::setAndReturn(ContractReceivableRepository::getErrCode());
            }
            return $result;
        } else {
            return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_CHANGE_RECEIVABLE_DATE_FORM_VERIFY_FAIL);
        }
    }

    /**
     * 将合同应收款标记为坏账
     * @param string $receivableId 应收款ID
     * @param string $isBadDebt 是否坏账 0：否，1：是
     * @return boolean true更新成功/false 更新失败
     */
    public function markBadDebt($receivableId, $isBadDebt)
    {
        $entity = ContractReceivableRepository::getContractReceivableById($receivableId);
        if (!isset($entity)) {
            return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_NOT_EXISTS);
        }

        if (floatval($entity->billing_amount) > 0 || floatval($entity->received_amount) > 0) {
            return ErrorInfo::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_MARK_BAD_DEBT_FORM_SAVE_FAIL, '', '应收款已关联了发票或回款，不允许当前操作');
        }

        $entity->is_bad_debt = $isBadDebt;
        $affectedRowNum = $entity->update();
        if ($affectedRowNum === false) {
            return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_MARK_BAD_DEBT_FORM_SAVE_FAIL);
        }

        return true;
    }

    /**
     * 将合同应收款标记为运营关注
     * @param string $receivableId 应收款ID
     * @param string $isOperation 是否运营关注项 0：否，1：是
     * @return boolean true更新成功/false 更新失败
     */
    public function markOperation($receivableId, $isOperation)
    {
        $entity = ContractReceivableRepository::getContractReceivableById($receivableId);
        if (!isset($entity)) {
            return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_NOT_EXISTS);
        }

        $entity->is_operation = $isOperation;
        $affectedRowNum = $entity->update();
        if ($affectedRowNum === false) {
            return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_MARK_OPERATION_FORM_SAVE_FAIL);
        }

        return true;
    }

    /**
     * 保存发票信息（与应收款的关系）
     * @param $invoiceModel
     * @return boolean|string   失败|发票Guid
     */
    public function saveInvoiceReceivable($invoiceModel)
    {
        if ($invoiceModel->validate()) {

            // 收据号码不为空时重复判断
            if ($invoiceModel->is_red_invoice != 1 && !empty($invoiceModel->invoice_no) && InvoiceService::exitSameInvoiceNo($invoiceModel->invoice_no, $invoiceModel->invoice_id)) {
                return $invoiceModel->is_receipt == 1 ? self::setAndReturn(ErrorCode::ERR_RECEIPT_NO_EXIST_SAME) : self::setAndReturn(ErrorCode::ERR_INVOICE_NO_EXIST_SAME);
            }

            // 开启事务
            $configDataBase = ConfigEntity::getDb();
            $trans = $configDataBase->beginTransaction();

            if (!empty($invoiceModel->contract_id)) {
                $invoiceModel->is_havecontract = 1;
            }
            if (isset($invoiceModel->invoice_id) && !empty($invoiceModel->invoice_id)) {
                //修改
                $result = InvoiceRepository::updateInvoice($invoiceModel);
            } else {
                //新增
                $result = InvoiceRepository::addInvoice($invoiceModel);
            }

            if ($result === false) {
                // 回滚事务
                $trans->rollBack();
                return self::setAndReturn(InvoiceRepository::getErrCode());
            } else {
                // 子发票的所有开票金额不能大于主发票的开票金额
                if ($invoiceModel->is_child_invoice == 1 && !empty($invoiceModel->main_invoice_id)) {
                    $res = InvoiceService::checkMainInvoiceAmountMorethanChildAmount($invoiceModel->main_invoice_id);
                    if ($res !== true) {
                        // 回滚事务
                        $trans->rollBack();
                        return ErrorInfo::setAndReturn(ErrorCode::ERR_INVOICE_FORM_SAVE_FAIL, '', '子发票的所有开票金额不能大于主发票的开票金额');
                    }
                }
                // 先删除原有的发票摘要
                $res = InvoiceSummaryRepository::deleteInvoiceSummaryByInvoiceId($result);
                if ($res !== true) {
                    // 回滚事务
                    $trans->rollBack();
                    return self::setAndReturn(InvoiceSummaryRepository::getErrCode());
                }

                // 再新增现有的发票摘要
                $invoiceSummarys = $invoiceModel->invoiceSummarys;
                if (isset($invoiceSummarys) && count($invoiceSummarys) > 0) {
                    foreach ($invoiceSummarys as $k => $v) {
                        $v['invoice_id'] = $result;
                        $v['summary_id'] = NULL;
                        $model = new InvoiceSummaryModel();
                        $model->load($v, '');
                        $res = InvoiceSummaryRepository::addInvoiceSummary($model);
                        if ($res === false) {
                            // 回滚事务
                            $trans->rollBack();
                            return self::setAndReturn(InvoiceSummaryRepository::getErrCode());
                        }
                    }
                }

                // 保存发票与应收款的对应关系
                $invoiceReceivables = $invoiceModel->invoiceReceivables;
                if (isset($invoiceReceivables) && count($invoiceReceivables) > 0) {
                    foreach ($invoiceReceivables as $k => $v) {
                        if (floatval($v['cur_billing_amount']) == 0) {
                            continue;
                        }

                        $v['invoice_id'] = $result;
                        $res = InvoiceReceivableRepository::saveInvoiceReceivable($v);
                        if ($res === false) {
                            // 回滚事务
                            $trans->rollBack();
                            return self::setAndReturn(InvoiceReceivableRepository::getErrCode());
                        }

                        // 重新刷新应收款的billing_amount
                        $res = self::summaryReceivablesAmount($v['receivable_id']);
                        if ($res === false) {
                            // 回滚事务
                            $trans->rollBack();
                            return self::setAndReturn(self::getErrCode());
                        }
                    }
                }

                // 如果是红冲发票
                if ($invoiceModel->is_red_invoice == 1) {
                    $res = $this->setPassiveRedInvoiceInfo($invoiceModel->red_by_invoice_id, $result);
                    if (!$res) {
                        // 回滚事务
                        $trans->rollBack();
                        return self::setAndReturn(ErrorCode::ERR_INVOICE_FORM_SAVE_FAIL);
                    }
                }

                // 重新刷新发票的receivable_amount
                $res = InvoiceService::summaryReceivablesAmount($result);
                if (!$res) {
                    // 回滚事务
                    $trans->rollBack();
                    return self::setAndReturn(InvoiceService::getErrCode());
                }

                // 重新刷新发票的payment_amount
                $res = InvoiceService::summaryInvoicePaymentAmount($result);
                if (!$res) {
                    // 回滚事务
                    $trans->rollBack();
                    return self::setAndReturn(InvoiceService::getErrCode());
                }

                // 提交事务
                $trans->commit();

                return $result;
            }
        } else {
            return self::setAndReturn(ErrorCode::ERR_INVOICE_FORM_VERIFY_FAIL);
        }
    }

    /**
     * 根据应收款ID重新刷新应收款的已开票金额(billing_amount)
     * @param string $receivableId 应收款id
     * @return boolean true刷新成功/false刷新失败
     */
    public static function summaryReceivablesAmount($receivableId)
    {
        $totalAmount = 0;
        $contractReceivable = ContractReceivableRepository::getContractReceivableById($receivableId);
        if (!isset($contractReceivable)) {
            return self::setAndReturn(ErrorCode::ERR_CONTRACT_RECEIVABLE_NOT_EXISTS);
        }

        $invoiceReceivables = InvoiceReceivableRepository::getInvoiceReceivablesByReceivableId($receivableId);
        if (isset($invoiceReceivables) && count($invoiceReceivables)) {
            foreach ($invoiceReceivables as $k => $v) {
                $totalAmount += floatval($v['cur_billing_amount']);
            }
        }

        $contractReceivable->billing_amount = $totalAmount;
        $result = $contractReceivable->update();
        if ($result === false) {
            return $result;
        }

        return true;
    }

    /**
     * 重新刷新应收款的已收金额(received_amount)
     * @param string $receivableId 应收款ID
     * @return boolean true刷新成功/false刷新失败
     */
    public static function summaryContractReceivableReceivedAmount($receivableId)
    {
        $contractReceivable = self::getContractReceivableEntity($receivableId);
        if (!isset($contractReceivable)) {
            return false;
        }

        $totalPaymentAmount = InvoicePaymentRepository::getTotalPaymentAmountByReceivableId($receivableId);
        $contractReceivable->received_amount = $totalPaymentAmount;
        $affectedRowNum = $contractReceivable->update();
        if ($affectedRowNum === false) {
            Yii::info("根据关联表算出来的应收金额：".$totalPaymentAmount,'income_item_log');
            Yii::info("应收表里的已结算金额：".$contractReceivable->received_amount,'income_item_log');
            return false;
        }

        return true;
    }

    /**
     * 设置被红冲发票的相关信息
     * 清空被红冲发票中的receivables_amount、payment_amount
     * 删除myscrm_invoice_payment对应的记录
     * 删除myscrm_invoice_receivable对应的记录
     * 重新刷新对应应收款中的billing_amount、received_amount
     * @param string $invoiceId 被红冲发票ID
     * @param string $redInvoiceId 红冲发票ID
     * @return boolean true刷新成功/false刷新失败
     */
    private function setPassiveRedInvoiceInfo($invoiceId, $redInvoiceId)
    {
        $invoice = InvoiceService::getInvoiceEntity($invoiceId);
        if (!isset($invoice)) {
            return self::setAndReturn(ErrorCode::ERR_INVOICE_NOT_EXISTS);
        }

        // 1、将被红冲发票的receivables_amount、payment_amount都设置成0
        $invoice->receivables_amount = 0;
        $invoice->payment_amount = 0;
        $invoice->red_by_invoice_id = $redInvoiceId;
        $invoice->modified_on = ConfigEntity::getDbNowDate();
        $result = $invoice->update();
        if ($result === false) {
            return self::setAndReturn(ErrorCode::ERR_INVOICE_FORM_SAVE_FAIL);
        }

        // 获取发票下的所有应收款
        $receivableIds = [];
        $invoiceReceivables = InvoiceReceivableRepository::getInvoiceReceivablesByInvoiceId($invoiceId);
        if (isset($invoiceReceivables) && count($invoiceReceivables) > 0) {
            foreach ($invoiceReceivables as $k => $v) {
                $receivableIds[] = $v['receivable_id'];
                // 2、删除myscrm_invoice_payment对应的记录
                $result = InvoicePaymentRepository::deleteInvoicePaymentByInvoiceReceivableId($v['invoice_receivable_id']);
                if (!$result) {
                    return self::setAndReturn(ErrorCode::ERR_INVOICE_FORM_SAVE_FAIL);
                }
            }
        }

        // 3、删除myscrm_invoice_receivable对应的记录
        $result = InvoiceReceivableRepository::deleteInvoiceReceivableByInvoiceId($invoiceId);
        if (!$result) {
            return self::setAndReturn(ErrorCode::ERR_INVOICE_FORM_SAVE_FAIL);
        }

        // 4、更新合同应收款中的billing_amount、received_amount
        foreach ($receivableIds as $k => $v) {
            $contractReceivableEntity = ContractReceivableRepository::getContractReceivableById($v);
            if (isset($contractReceivableEntity)) {
                $billingAmount = InvoiceReceivableRepository::getTotalBillingAmountByReceivableId($v);
                $receivedAount = InvoicePaymentRepository::getTotalPaymentAmountByReceivableId($v);

                $contractReceivableEntity->billing_amount = $billingAmount;
                $contractReceivableEntity->received_amount = $receivedAount;
                $result = $contractReceivableEntity->update();
                if ($result === false) {
                    return self::setAndReturn(ErrorCode::ERR_INVOICE_FORM_SAVE_FAIL);
                }
            }
        }

        return true;
    }

    /**
     * 根据应收款项Id获取对应的应收款
     * @param string $receivableId 应收款项Id
     * @return \common\entities\myhtsq\ContractReceivableEntity
     */
    public static function getContractReceivableEntity($receivableId)
    {
        return ContractReceivableRepository::getContractReceivableById($receivableId);
    }

    /**
     * 根据合同ID获取对应的发票与应收款对应关系
     * @param string $contractId
     * @return array
     */
    public function getInvoiceReceivableInfoByContractId($contractId)
    {
        $invoiceReceivableInfos = InvoiceReceivableRepository::getInvoiceReceivablesByContractId($contractId);
        $result = [];
        if (isset($invoiceReceivableInfos) && count($invoiceReceivableInfos) > 0) {
            // 叠加回款信息
            foreach ($invoiceReceivableInfos as $k => $v) {
                $totalPayment = 0;
                $financeCode = [];
                $invoicePayments = InvoicePaymentRepository::getInvoicePaymentByInvoiceReceivableId($v['invoice_receivable_id']);
                if (isset($invoicePayments) && count($invoicePayments) > 0) {
                    foreach ($invoicePayments as $k1 => $v1) {
                        $totalPayment += floatval($v1['cur_payment_amount']);
                        if (!in_array($v1['finance_code'], $financeCode)) {
                            $financeCode[] = $v1['finance_code'];
                        }
                    }
                }

                /*$cur_billing_amount = $v['cur_billing_amount'];
                if ($cur_billing_amount - $totalPayment != 0) {
                    $invoiceReceivableInfos[$k]['total_payment'] = $totalPayment;
                    $invoiceReceivableInfos[$k]['finance_code'] = implode(';', $financeCode);
                    $result[] = $invoiceReceivableInfos[$k];
                }*/
                $invoiceReceivableInfos[$k]['total_payment'] = $totalPayment;
                $invoiceReceivableInfos[$k]['finance_code'] = implode(';', $financeCode);
                $result[] = $invoiceReceivableInfos[$k];
            }
        }

        return $result;
    }

    /**
     * 应收时间到期前7天
     */
    public function receivableExpiredRemind()
    {
        $expiredDate = date_add(date_create_from_format('Y-m-d H:i:s', ConfigEntity::getDbNowDate()), \DateInterval::createFromDateString('7 Day'));
        $expiredDate = date_format($expiredDate, 'Y-m-d');
        //获取7天到期的应收款
        $expiredReceivables = ContractReceivableRepository::getReceivableExpiredRemind($expiredDate);
        foreach ($expiredReceivables as $key => $item) {
            //获取合同累计回款金额
            $totalRefundAmount = InvoicePaymentRepository::getTotalPaymentAmountByContractId($item['contract_id']);
            //获取合同信息
            $contractInfo = ContractManageRepository::getContractManageModelByContractId($item['contract_id']);
            $emailParams = [
                'contractId' => $contractInfo->contract_code,
                'custName' => $contractInfo->customer_name,
                'contractAmount' => $contractInfo->sign_amount,
                'receivableAmount' => $item['receivable_amount'],
                'totalReceivedAmount' => $totalRefundAmount,
                'receivableDate' => $item['receivable_date']
            ];
            $this->sendEmail($item['payee_id'], '【合同管理】应收信息', 'receivableExpired', $emailParams, []);
        }

    }

    private function sendEmail($userId, $subject, $template, $params, $cc)
    {
        $user = ErpUserRepository::getUserById($userId);
        if (empty($user)) {
            return;
        }
        //获取抄送人
        $copyToEMail = ContractEmailContactsRepository::getCCContactsByBu($user['BUGUID'], $user['UserCode']);

        $params['ScrmUrl'] = \Yii::$app->params['ScrmUrl'];
        $params['userName'] = $user['UserName'];

        if (is_array($cc)) {
            $copyToEMail = array_merge($copyToEMail, $cc);
        }
        $params['ScrmUrl'] = \Yii::$app->params['ScrmUrl'];
        return EmailService::sendEMail([$user['Email'] => $user['UserName']], $subject, 'contract/' . $template, $params, $copyToEMail);
    }


    /**
     * Method getPaymentInfoByContractBusinessType
     * 根据合同业务类型获取不同的应收信息
     *
     * @param string $contractId
     * @param string $contract_business_type
     *
     * @return array|bool|\yii\db\ActiveRecord[]
     */
    public function getPayInfoByContractId($contractId = '') {
        if (empty($contractId)) {
            return false;
        }

        try {
            return ContractPayinfoRepository::getPayInfoByContractId($contractId);
        } catch (Exception $e) {
            return false;
        }
    }

    /**
     * 根据合同id获取供应商线下活动支付信息
     * @param string $contractId
     *
     * @return array|bool|\yii\db\ActiveRecord[]
     */
    public function getSuppliersPaymentByContractId($contractId = '') {
        if (empty($contractId)) {
            return false;
        }

        try {
            $result =  ContractSuppliersPaymentRepository::getPaymentListByContractid($contractId);

            foreach ($result as &$re) {
                // 时间处理
                $re['sign_up_time'] = date('Y-m-d', strtotime($re['sign_up_time']));
            }

            return $result;
        } catch (Exception $e) {
            return false;
        }
    }

}
